package com.tqyan.service.service.impl;

import com.tqyan.dal.mapper.UserMapper;
import com.tqyan.dal.mapper.UserSettingMapper;
import com.tqyan.model.controller.response.UserResp;
import com.tqyan.model.dto.AccountDTO;
import com.tqyan.model.dto.UserDTO;
import com.tqyan.model.dto.UserSettingDTO;
import com.tqyan.model.dto.WechatUserDTO;
import com.tqyan.model.enums.ChatCreativeAbilityEnum;
import com.tqyan.model.enums.ChatModelEnum;
import com.tqyan.model.enums.UserStatusEnum;
import com.tqyan.model.exp.DefaultException;
import com.tqyan.service.service.AccountService;
import com.tqyan.service.service.UserService;
import com.tqyan.util.SnowflakeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 用户服务
 * <p> <功能详细描述> </p>
 *
 * @author 陈晨
 * @version 1.0
 * @date 2023/4/12
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserSettingMapper userSettingMapper;

    @Autowired
    private AccountService accountService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserResp wechatLogin(WechatUserDTO wechatUser) {
        if (null == wechatUser) {
            throw new DefaultException("登录信息不可为空");
        }
        if (StringUtils.isBlank(wechatUser.getOpenId())) {
            throw new DefaultException("openId不可为空");
        }
        // 获取用户信息
        UserDTO user = userMapper.queryByOpenId(wechatUser.getOpenId());
        boolean isRegister = false;
        if (null == user) {
            // 注册新用户
            user = this.register(wechatUser);
            isRegister = true;
        }
        // 获取用户设置
        UserSettingDTO userSetting = userSettingMapper.queryByUser(user.getId());
        // 获取用户余额
        AccountDTO account = accountService.queryByUser(user.getId());
        // 设置相应信息
        UserResp resp = new UserResp();
        resp.setOpenId(user.getOpenId());
        resp.setFace(user.getFace());
        resp.setNickname(user.getNickname());
        resp.setModel(userSetting.getModel());
        resp.setCreativeAbility(userSetting.getCreativeAbility());
        resp.setOpenAiKey(userSetting.getOpenAiKey());
        resp.setAccount(account.getAccount() / 100D);
        resp.setIsRegister(isRegister);
        // 更新最后登录时间
        userMapper.updateLoginTime(user.getId());
        return resp;
    }

    @Override
    public UserResp getUserInfoAll(String openId) {
        if (StringUtils.isBlank(openId)) {
            throw new DefaultException("openId不可为空");
        }
        // 获取用户信息
        UserDTO user = this.getUserInfo(openId);
        // 获取用户设置
        UserSettingDTO userSetting = userSettingMapper.queryByUser(user.getId());
        // 获取用户余额
        AccountDTO account = accountService.queryByUser(user.getId());
        // 设置相应信息
        UserResp resp = new UserResp();
        resp.setOpenId(user.getOpenId());
        resp.setFace(user.getFace());
        resp.setNickname(user.getNickname());
        resp.setModel(userSetting.getModel());
        resp.setCreativeAbility(userSetting.getCreativeAbility());
        resp.setOpenAiKey(userSetting.getOpenAiKey());
        resp.setAccount(account.getAccount() / 100D);
        return resp;
    }

    @Override
    public UserDTO getUserInfo(String openId) {
        if (StringUtils.isBlank(openId)) {
            throw new DefaultException("请授权登录");
        }
        UserDTO user = userMapper.queryByOpenId(openId);
        if (null == user) {
            throw new DefaultException("用户信息不存在");
        }
        if (UserStatusEnum.NORMAL.getValue() != user.getStatus()) {
            throw new DefaultException("微信号存在风险, 禁止使用");
        }
        return user;
    }

    /**
     * @description 注册新用户
     * <p> <功能详细描述> </p>
     *
     * @author 陈晨
     * @date 2023/4/12 00:58
     */
    private UserDTO register(WechatUserDTO wechatUser) {
        // 用户信息
        UserDTO user = new UserDTO();
        user.setId(SnowflakeUtils.nextId());
        user.setOpenId(wechatUser.getOpenId());
        user.setFace(wechatUser.getFace());
        user.setNickname(wechatUser.getNickname());
        user.setStatus(UserStatusEnum.NORMAL.getValue());
        user.setReference(wechatUser.getReference());
        boolean result = userMapper.save(List.of(user)) > 0;
        log.info("[注册新用户] wechatUser={}, 用户信息, 入库【{}】", wechatUser, result);
        // 用户设置信息
        UserSettingDTO userSetting = new UserSettingDTO();
        userSetting.setUserId(user.getId());
        userSetting.setModel(ChatModelEnum.RELATION.getValue());
        userSetting.setCreativeAbility(ChatCreativeAbilityEnum.TEMPERATURE_1_0.getValue());
        result = userSettingMapper.save(List.of(userSetting)) > 0;
        log.info("[注册新用户] wechatUser={}, 用户设置信息, 入库【{}】", wechatUser, result);
        // 推荐人赠送1元
        if (StringUtils.isNotBlank(user.getReference())) {
            UserDTO reference = userMapper.queryByOpenId(user.getReference());
            if (null != reference) {
                result = accountService.gift(reference.getId(), 100
                        , "推荐新用户: (" + user.getId() + ") " + user.getNickname());
                log.info("[注册新用户] wechatUser={}, 推荐人赠送1元, 入库【{}】", wechatUser, result);
            }
        }
        return user;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setModel(String openId, int model) {
        if (StringUtils.isBlank(openId)) {
            throw new DefaultException("openId不可为空");
        }
        ChatModelEnum modelEnum = ChatModelEnum.get(model);
        if (null == modelEnum) {
            throw new DefaultException("会话模式错误");
        }
        // 获取用户信息
        UserDTO user = userMapper.queryByOpenId(openId);
        if (null == user) {
            throw new DefaultException("用户信息不存在");
        }
        UserSettingDTO userSetting = new UserSettingDTO();
        userSetting.setUserId(user.getId());
        userSetting.setModel(model);
        boolean result = userSettingMapper.update(userSetting) > 0;
        log.info("[用户设置] openId={}, model={}, 会话模式, 设置【{}】", openId, model, result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setCreativeAbility(String openId, int creativeAbility) {
        if (StringUtils.isBlank(openId)) {
            throw new DefaultException("openId不可为空");
        }
        ChatCreativeAbilityEnum creativeAbilityEnum = ChatCreativeAbilityEnum.get(creativeAbility);
        if (null == creativeAbilityEnum) {
            throw new DefaultException("创造力错误");
        }
        // 获取用户信息
        UserDTO user = userMapper.queryByOpenId(openId);
        if (null == user) {
            throw new DefaultException("用户信息不存在");
        }
        UserSettingDTO userSetting = new UserSettingDTO();
        userSetting.setUserId(user.getId());
        userSetting.setCreativeAbility(creativeAbility);
        boolean result = userSettingMapper.update(userSetting) > 0;
        log.info("[用户设置] openId={}, creativeAbility={}, 创造力, 设置【{}】", openId, creativeAbility, result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setOpenAiKey(String openId, String openAiKey) {
        if (StringUtils.isBlank(openId)) {
            throw new DefaultException("openId不可为空");
        }
        if (StringUtils.isBlank(openAiKey)) {
            throw new DefaultException("Key不可为空");
        }
        // 获取用户信息
        UserDTO user = userMapper.queryByOpenId(openId);
        if (null == user) {
            throw new DefaultException("用户信息不存在");
        }
        UserSettingDTO userSetting = new UserSettingDTO();
        userSetting.setUserId(user.getId());
        userSetting.setOpenAiKey(openAiKey);
        boolean result = userSettingMapper.update(userSetting) > 0;
        log.info("[用户设置] openId={}, openAiKey={}, 设置【{}】", openId, openAiKey, result);
        return result;
    }

}


